package com.citicpub_cloud.restfull.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.citicpub_cloud.restfull.api.dto.ChapterDTO;
import com.citicpub_cloud.restfull.api.dto.ExcelDTO;
import com.citicpub_cloud.restfull.api.dto.GoodsInfoDTO;
import com.citicpub_cloud.restfull.api.dto.MixResDTOExt;
import com.citicpub_cloud.restfull.service.ResourceService;

/**
 * @Description： 打包类型文件夹并且生成Excel文件
 * 
 */
public class AppendZipAndExcelRunner implements Runnable {

	private static Logger log = LoggerFactory.getLogger(AppendZipAndExcelRunner.class);
	
	private static int FILE_MAX_SIZE = 5 * 1024 * 1024;
	
	private int gtype;
	
	private int rtype;
	
	private List<GoodsInfoDTO> goodslist;
	
	private String threadname;
	
	private Map<String,String> zipmap;
	
	private File zipFile;

	private ResourceService resourceService;

	private FileOutputStream out = null;
	
	
	public AppendZipAndExcelRunner(ResourceService resourceService,int gtype,int rtype,List<GoodsInfoDTO> goodslist,String threadname,Map<String,String> zipmap,File zipFile) {
		this.gtype = gtype;
		this.rtype = rtype;
		this.goodslist = goodslist;
		this.threadname = threadname;
		this.zipmap = zipmap;
		this.zipFile = zipFile;
		this.resourceService = resourceService;		
	}

	@SuppressWarnings("finally")
	@Override
	public void run() {
		try{
			String zipName = zipFile.getName();
			String typeFilePath = zipFile.getAbsolutePath();
			List<ExcelDTO> exceldatas = new ArrayList<ExcelDTO>();
				
			for(int i=0;i<goodslist.size();i++){
				ExcelDTO tmpdata = null;
				
				Long contentAlbumId = goodslist.get(i).getContentAlbumId();
				String goodsname = goodslist.get(i).getGoodsName();
				String goodsimg = goodslist.get(i).getGoodsImg();
				String goodsdesc = goodslist.get(i).getGoodsDesc();
				String resauthor = goodslist.get(i).getResAuthor();
				String goodsnum = goodslist.get(i).getGoodsNum();
				boolean resourceFetchFlag = true;
				
				log.info("------线程:{},开始处理第{}个资源文件,商品编码:{},商品名称{}", threadname,(i+1), goodsnum, goodsname);			
							
			
				if (!StringUtils.isBlank(goodsname) && !StringUtils.isBlank(goodsimg)) {
					MixResDTOExt mixresobj = resourceService.getResourceContentById(gtype, contentAlbumId, goodsname, goodsimg);
						
						
					if(null != mixresobj) {	
						List<ChapterDTO> chapterlist = mixresobj.getChapterlist();
					
						if(chapterlist.size() > 0) {
							tmpdata = new ExcelDTO();
							
							String tmpName = replaceSpecialFileName(mixresobj.getTitle());
						
							//资源文件夹路径
							String resourceInTypeExcelPath = "/" + UploadUtils.combinePath(zipName, tmpName);
							String resourceInTypeFilePath = UploadUtils.combinePath(typeFilePath, tmpName);
						
							//资源封面路径
							String imgurl = mixresobj.getImgUrl();
							int imgIndex = imgurl.lastIndexOf(".");
							String imgsuffix = imgurl.substring(imgIndex);
							String imgResourceExcelPath = "/" + UploadUtils.combinePath(zipName, tmpName + imgsuffix);
							String imgResourceFilePath = UploadUtils.combinePath(typeFilePath, tmpName + imgsuffix);
							
							log.info("------线程:{},开始处理第{}个资源文件中的封面,商品编码:{},商品名称:{},url:{}",threadname,(i+1), goodsnum, goodsname,imgurl);
							if(!StringUtils.isBlank(imgurl)) {
								byte[] buf = OSSManageUtil.downloadImgRemotFile(imgurl);
								if(buf != null) {
									writeFile(imgResourceFilePath, buf);
								}
							
							
								File imgfile = new File(imgResourceFilePath);
								if(imgfile.exists()) {
									File resourceDir = new File(resourceInTypeFilePath);
									if(!resourceDir.exists()) {
										resourceDir.mkdir();
									}
									
									for(int j=0;j<chapterlist.size();j++){		

										ChapterDTO obj = chapterlist.get(j);
									
										String chaptername = obj.getTitle();
										String ordernum = obj.getOrdernum();
										String chapterurl = obj.getChapterUrl();
										long chaptersize = obj.getChapterSize().longValue();
										
										if(resourceFetchFlag){
											log.info("------线程:{},开始处理第{}个资源文件中的第{}个章节,商品编码:{},商品名称:{},url:{}", threadname,(i+1),(j+1), goodsnum, goodsname,chapterurl);
											
										
											if(!"".equals(ordernum)) {
												String newordernum = "";
												if(ordernum.length() == 1) {
													newordernum = "00" + ordernum;
												}
												if(ordernum.length() == 2) {
													newordernum = "0" + ordernum;
												}
												if(ordernum.length() == 3) {
													newordernum = ordernum;
												}
										        
										        String newname = newordernum + chaptername;
										        chaptername = newname;
											}
										
											//资源文件夹中章节路径
											if(!StringUtils.isBlank(chapterurl)) {
												if(chaptersize == 0){
													chaptersize = OSSManageUtil.getContentLength(chapterurl);
												}
												
												int chapterIndex = chapterurl.indexOf(".");
												String chaptersuffix = chapterurl.substring(chapterIndex);
												
												String chapterResourceFilePath = UploadUtils.combinePath(resourceInTypeFilePath, chaptername + chaptersuffix);
											
												if(chaptersize < FILE_MAX_SIZE) {
													byte[] chapterbuf = OSSManageUtil.downloadOtherRemoteFile(chapterurl);
													
													if (chapterbuf != null) {
														writeFile(chapterResourceFilePath, chapterbuf);
													}
												} else {
													OSSManageUtil.downloadFile1(chapterurl, chapterResourceFilePath);
												}
												
												
												File chapterfile = new File(chapterResourceFilePath);
												if(!chapterfile.exists()) {
													resourceFetchFlag = false;
												}
											} else {
												resourceFetchFlag = false;
											}
										} else {
											log.info("------线程:{},忽略处理第{}个资源文件中的第{}个章节,商品编码:{},商品名称:{},url:{}", threadname,(i+1),(j+1), goodsnum, goodsname,chapterurl);
										}
									}	
									
									if(resourceFetchFlag) {
										tmpdata.setShowGroup("5002");
										tmpdata.setShowType("" + rtype);
										tmpdata.setShowtitle(goodsname);
										tmpdata.setShowAuthor(resauthor);
										tmpdata.setShowDesc(goodsdesc);
										tmpdata.setShowImgPath(imgResourceExcelPath);
										tmpdata.setShowResourcesPath(resourceInTypeExcelPath);
										if(10 == gtype){
											tmpdata.setShowReadOrListen("收听类");
										} else {
											tmpdata.setShowReadOrListen("");
										}
										exceldatas.add(tmpdata);
									} else {
										imgfile.delete();
										deleteFile(resourceDir);
										log.info("------线程:{},有问题的商品编码{}",threadname,goodsnum);
									}
													
								} else {
									log.info("------线程:{},有问题的商品编码{}",threadname,goodsnum);
								}
							} else {
								log.info("------线程:{},有问题的商品编码{}",threadname,goodsnum);
							}
						} else {
							log.info("------线程:{},有问题的商品编码{}",threadname,goodsnum);
						}
					} else {
						log.info("------线程:{},有问题的商品编码{}",threadname,goodsnum);
					}
				} else {
					log.info("------线程:{},有问题的商品编码{}",threadname,goodsnum);
				}
			}
			
			
			if(exceldatas.size() > 0) {
				log.info("------线程:{},结束处理文件夹{}内容", threadname,zipName);
				
				log.info("------线程:{},开始生成压缩包", threadname,zipName);
				
				
				ZipUtils.createZip(typeFilePath, typeFilePath + ".zip");
				deleteFile(zipFile);
				
				log.info("------线程:{},结束生成压缩包", threadname,zipName);
				
				
				log.info("------线程:{},开始生成对应Excel", threadname,zipName);
				out = new FileOutputStream(typeFilePath + ".xls");
				HSSFWorkbook workBook = new HSSFWorkbook();
				HSSFSheet mySheet = workBook.createSheet();
				workBook.setSheetName(0, "sheet1");
				int rowNomber=-1;
				
				for (ExcelDTO obj :  exceldatas) {
					HSSFRow myRow = mySheet.createRow(++rowNomber);
					
					//第一列
					HSSFCell cell0 = myRow.createCell((short) 0);
					cell0.setCellValue(obj.getShowGroup());
					
					HSSFCell cell1 = myRow.createCell((short) 1);
					cell1.setCellValue(obj.getShowType());				
					
					HSSFCell cell2 = myRow.createCell((short) 2);
					cell2.setCellValue(obj.getShowtitle());
					
					HSSFCell cell3 = myRow.createCell((short) 3);
					cell3.setCellValue(obj.getShowAuthor());
					
					HSSFCell cell4 = myRow.createCell((short) 4);
					cell4.setCellValue(obj.getShowDesc());
					
					HSSFCell cell5 = myRow.createCell((short) 5);
					cell5.setCellValue(obj.getShowImgPath());
					
					HSSFCell cell6 = myRow.createCell((short) 6);
					cell6.setCellValue(obj.getShowResourcesPath());
					
					HSSFCell cell7 = myRow.createCell((short) 7);
					cell7.setCellValue(obj.getShowReadOrListen());
				}
				
				workBook.write(out);
				log.info("------线程:{},结束生成对应Excel", threadname,zipName);
			} else {
				deleteFile(zipFile);
				log.info("------线程:{},所有资源均没有打包", threadname);
			}
		} catch (Throwable e) {
			log.error("导出内容出错",e);
			e.printStackTrace();
		} finally {
			// 开关置成完成解析状态
			zipmap.put(threadname, "0");
			
			if (null != out) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	 public void deleteFile(File file){
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()){
            return;
        }
	    //取得这个目录下的所有子文件对象
	    File[] files = file.listFiles();
	    //遍历该目录下的文件对象
        for (File f: files){
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()){
                deleteFile(f);
            }else {
                f.delete();
            }
        }
        //删除空文件夹  for循环已经把上一层节点的目录清空。
        file.delete();
    }
	
	
	public String replaceSpecialFileName(String oldName) {
		String newName = "";
		String[] allchars = {"\\","/",":","*","?","\"","<",">","|"};
		
		for(int i=0;i<allchars.length;i++) {
			if(!"".equals(newName)){
				oldName = newName;
			}
			
			newName = oldName.replace(allchars[i], "");
		}
		
		return newName;
	}
	
	public void writeFile(String path, byte[] bytes) {
		FileOutputStream out = null;
	    try {
	    	out = new FileOutputStream(path);
	        FileChannel fileChannel = out.getChannel();
	        fileChannel.write(ByteBuffer.wrap(bytes)); //将字节流写入文件中
	        fileChannel.force(true);//强制刷新
	        fileChannel.close();
	    } catch (FileNotFoundException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    } finally {
	    	try{
	    		if (out != null) {
		    		out.close();
		    	}
	    	} catch (IOException e) {
	    		e.printStackTrace();
	    	}
	    	
	    }
	}
}

